#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import os
import os.path

from common.common import read_platform_result_file, write_content_to_file
from common.file_common import delete_path
from oracle import logger
from oracle.schemas.oracle_schemas import DBFile, DBInfo


class CopyDBInfo:
    def __init__(self, db_id: str, unique_name: str, db_instance: str, asm_user: str = "",
                 asm_id_name: str = "", db_is_cluster: str = "", ora_pre_version_extend: str = "",
                 incarnation_num: str = "", resetlogs_id: str = "", ora_version: str = ""):
        self.db_id = db_id
        self.unique_name = unique_name
        self.db_instance = db_instance
        self.asm_user = asm_user
        self.asm_id_name = asm_id_name
        self.db_is_cluster = db_is_cluster
        self.ora_pre_version_extend = ora_pre_version_extend
        self.incarnation_number = incarnation_num
        self.resetlogs_id = resetlogs_id
        self.ora_version = ora_version

    def check_version(self, oracle_major_version: str) -> bool:
        logger.info(f"self.pre_version:{self.ora_pre_version_extend},major_version:{oracle_major_version}")
        return self.ora_pre_version_extend[0:2] == oracle_major_version


def get_copy_db_info(data_path: str):
    """
    读取备份的dbinfo
    :param data_path:
    :return:
    """
    db_info_path = os.path.join(data_path, "additional", "dbinfo")
    if not os.path.exists(db_info_path):
        logger.error(f"Database info path does not exist: {db_info_path}")
        return None
    try:
        file_content = read_platform_result_file(db_info_path).strip()
        dbinfo_content_list = file_content.split(';')
        if len(dbinfo_content_list) < 10:
            logger.error(f"Invalid content in database info file: {db_info_path}")
            return None
        return CopyDBInfo(
            db_id=dbinfo_content_list[0],
            unique_name=dbinfo_content_list[1],
            db_instance=dbinfo_content_list[2],
            asm_user=dbinfo_content_list[3],
            asm_id_name=dbinfo_content_list[4],
            db_is_cluster=dbinfo_content_list[5],
            ora_pre_version_extend=dbinfo_content_list[6],
            incarnation_num=dbinfo_content_list[7],
            resetlogs_id=dbinfo_content_list[8],
            ora_version=dbinfo_content_list[9]
        )
    except Exception as exception_str:
        logger.error(f"An error occurred while reading the database info file: {exception_str}")
        return None


def get_copy_files(data_path: str) -> [DBFile]:
    db_info_path = os.path.join(data_path, "additional", "dbfiles")
    try:
        dbfiles_result = []
        dbfiles_lines = read_platform_result_file(db_info_path).splitlines()
        for line in dbfiles_lines:
            line_result = line.strip().split(';')
            db_file = DBFile(con_id=line_result[0], ts_name=line_result[1],
                             file_no=line_result[2], ts_file=line_result[3])
            dbfiles_result.append(db_file)
        return dbfiles_result
    except Exception as exception_str:
        logger.error(f"An error occurred while reading the dbfiles: {exception_str}")
        return []


def write_db_files(db_files: [DBFile], data_path: str):
    db_files_path = os.path.join(data_path, "additional", "dbfiles")
    if os.path.exists(db_files_path):
        delete_path(db_files_path)
        logger.info(f"delete path:{db_files_path}")
    db_file_lines = [f"{item.con_id};{item.ts_name};{item.file_no};{item.ts_file}" for item in db_files]
    file_content = "\n".join(db_file_lines)
    write_content_to_file(db_files_path, file_content)


def write_db_info(db: DBInfo, data_path: str, **kwargs):
    db_info_path = os.path.join(data_path, "additional", "dbinfo")
    if os.path.exists(db_info_path):
        delete_path(db_info_path)
        logger.info(f"delete path:{db_info_path}")
    file_content = f"{db.db_id};{db.db_unique_name};{db.inst_name};{kwargs.get('asm_user')};" \
                   f"{kwargs.get('asm_inst_name')};{kwargs.get('db_cluster')};" \
                   f"{kwargs.get('major_version')};{db.incarnation};{db.resetlogs_id};{kwargs.get('version')}"
    write_content_to_file(db_info_path, file_content)


def write_env_file(oracle_base: str, oracle_home, data_path: str):
    env_file_path = os.path.join(data_path, "additional", "env_file")
    if os.path.exists(env_file_path):
        delete_path(env_file_path)
        logger.info(f"delete path:{env_file_path}")
    oracle_info = f"ORACLE_BASE={oracle_base}\nORACLE_HOME={oracle_home}"
    write_content_to_file(env_file_path, oracle_info)


def write_log_files(online_redo_log: str, data_path: str):
    env_file_path = os.path.join(data_path, "additional", "logfiles")
    if os.path.exists(env_file_path):
        delete_path(env_file_path)
        logger.info(f"delete path:{env_file_path}")
    write_content_to_file(env_file_path, online_redo_log)
